home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / docs / linux-do / programm / lpg-0.4 / lpg-0 / LPG / examples / miniterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  3.5 KB  |  132 lines

  1. /*
  2.  *  AUTHOR: Sven Goldt (goldt@math.tu-berlin.de)
  3.  *
  4.  *  This program is free software; you can redistribute it and/or
  5.  *  modify it under the terms of the GNU General Public License
  6.  *  as published by the Free Software Foundation; either version 2
  7.  *  of the License, or (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14. */
  15. /*
  16.  This is like all programs in the Linux Programmer's Guide meant
  17.  as a simple practical demonstration.
  18.  It can be used as a base for a real terminal program.
  19. */
  20.  
  21. #include <termios.h>
  22. #include <stdio.h>
  23. #include <unistd.h>
  24. #include <fcntl.h>
  25. #include <sys/signal.h>
  26.  
  27. #define BAUDRATE B38400
  28. #define MODEMDEVICE "/dev/modem"
  29. #define ENDMINITERM 2 /* ctrl-b to quit miniterm */
  30.  
  31. #define _POSIX_SOURCE 1 /* POSIX compliant source */
  32.  
  33. #define FALSE 0
  34. #define TRUE 1
  35.  
  36. volatile int STOP=FALSE; 
  37.  
  38. void child_handler(int s)
  39. {
  40.    STOP=TRUE;
  41. }
  42.  
  43. main()
  44. {
  45. int fd,c;
  46. struct termios oldtio,newtio,oldstdtio,newstdtio;
  47. struct sigaction sa;
  48.  
  49. /* 
  50.   Open modem device for reading and writing and not as controlling tty
  51.   because we don't want to get killed if linenoise sends CTRL-C.
  52. */
  53.  fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY);
  54.  if (fd <0) {perror(MODEMDEVICE); exit(-1); }
  55.  
  56.  tcgetattr(fd,&oldtio); /* save current modem settings */
  57.  
  58. /* 
  59.   Set bps rate and hardware flow control and 8n1 (8bit,no parity,1 stopbit).
  60.   Also don't hangup automatically and ignore modem status.
  61.   Finally enable receiving characters.
  62. */
  63.  newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  64.  
  65. /*
  66.  Ignore bytes with parity errors and make terminal raw and dumb.
  67. */
  68.  newtio.c_iflag = IGNPAR;
  69.  
  70. /*
  71.  Raw output.
  72. */
  73.  newtio.c_oflag = 0;
  74.  
  75. /*
  76.  Don't echo characters because if you connect to a host it or your
  77.  modem will echo characters for you. Don't generate signals.
  78. */
  79.  newtio.c_lflag = 0;
  80.  
  81. /* blocking read until 1 char arrives */
  82.  newtio.c_cc[VMIN]=1;
  83.  newtio.c_cc[VTIME]=0;
  84.  
  85. /* now clean the modem line and activate the settings for modem */
  86.  tcflush(fd, TCIFLUSH);
  87.  tcsetattr(fd,TCSANOW,&newtio);
  88.  
  89. /*
  90.   Strange, but if you uncomment this command miniterm will not work
  91.   even if you stop canonical mode for stdout. This is a linux bug.
  92. */
  93.  tcsetattr(1,TCSANOW,&newtio); /* stdout settings like modem settings */
  94.  
  95. /* next stop echo and buffering for stdin */
  96.  tcgetattr(0,&oldstdtio);
  97.  tcgetattr(0,&newstdtio); /* get working stdtio */
  98.  newstdtio.c_lflag &= ~(ICANON | ECHO);
  99.  tcsetattr(0,TCSANOW,&newstdtio);
  100.  
  101. /* terminal settings done, now handle in/ouput */
  102.  switch (fork())
  103.  {
  104.   case 0: /* child */
  105.    /* user input */
  106.    close(1); /* stdout not needed */
  107.    for (c=getchar(); c!= ENDMINITERM ; c=getchar()) write(fd,&c,1);
  108.    tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */
  109.    tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */
  110.    close(fd);
  111.    exit(0); /* will send a SIGCHLD to the parent */
  112.    break;
  113.   case -1:
  114.    perror("fork");
  115.    tcsetattr(fd,TCSANOW,&oldtio);
  116.    close(fd);
  117.    exit(-1);
  118.   default: /* parent */
  119.    close(0); /* stdin not needed */
  120.    sa.sa_handler = child_handler;
  121.    sa.sa_flags = 0;
  122.    sigaction(SIGCHLD,&sa,NULL); /* handle dying child */
  123.    while (STOP==FALSE) /* modem input handler */
  124.    {
  125.     read(fd,&c,1); /* modem */
  126.     write(1,&c,1); /* stdout */
  127.    }
  128.    wait(NULL); /* wait for child to die or it will become a zombie */
  129.    break;
  130.  }
  131. }
  132.